package com.xz.courseschedule.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xz.courseschedule.common.dto.TimeTableClassDto;
import com.xz.courseschedule.common.dto.TimetableDto;
import com.xz.courseschedule.common.vo.BaseVo;
import com.xz.courseschedule.entity.*;
import com.xz.courseschedule.mapper.TimetableMapper;
import com.xz.courseschedule.mapper.TimetableRechearsalMapper;
import com.xz.courseschedule.service.*;
import com.xz.courseschedule.utils.ClassUtil;
import com.xz.courseschedule.utils.Result;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * @Author: zys
 * @CreateTime: 2025-05-25
 */

@Service
public class TimetableServiceImpl extends ServiceImpl<TimetableMapper, Timetable> implements TimetableService {

    @Autowired
    private TimetableMapper timetableMapper;

    @Autowired
    private TimetableRechearsalMapper timetableRechearsalMapper;


    @Resource
    private RoomService roomService;
    @Resource
    private CourseService courseService;
    @Resource
    private ClassesService classesService;
    @Resource
    private TeacherService teacherService;

    @Resource
    private SemesterService semesterService;




    /*****************************手动排课的冲突检查*************************************/
    //获取冲突字段名列表(教师编号 班级编号 教室编号)
    @Override
    public Result getConflictingColumnNameList(Long semesterId, String columnName) {
        boolean columnNameError = !"class_no".equals(columnName) && !"teacher_no".equals(columnName) && !"room_no".equals(columnName);
        if (columnNameError){
            return Result.error(400,"传入字段名columnName有误");
        }
        List<String> list = timetableMapper.getConflictingColumnNameList(semesterId, columnName);
        String msg = "成功获取" + semesterId + "学期课表中存在冲突的"+columnName+"列表";
        return Result.success(msg,list);
    }

    //获取时间冲突的任务 ID
    @Override
    public Result getConflictingTimeslotIdList(Long semesterId, String columnName, String no) {
        boolean columnNameError = !"class_no".equals(columnName) && !"teacher_no".equals(columnName) && !"room_no".equals(columnName);
        if (columnNameError) {
            return Result.error(400,"传入字段名columnName有误");
        }
        List<Long> list = timetableMapper.getConflictingTimeslotIdList(semesterId, columnName, no);
        String msg = "成功获取" + semesterId + "学期课表中" + columnName + "=" + no +"存在冲突的timetable.id";
        return Result.success(msg,list);
    }

    //获取单个任务的所有冲突
    @Override
    public Result getConfilctList(Long id) {
        Timetable timetable = super.getById(id);
        if (timetable == null){
            return Result.error(400,"待查询课表字段不存在!");
        }
        List<TimetableDto> list = timetableMapper.getConfilctList(id);
        String msg = "成功获取与timetable.id="+id+"存在冲突的其他timetable.*，并返回冲突类型";
        return Result.success(msg,list);
    }

    //自动调整时间解决冲
    @Override
    public Result rehearsalChangeTimeslot(Long id) {
        Timetable timetable = super.getById(id);
        if (timetable == null){
            return Result.error(400,"待查询课表字段不存在!");
        }

        //1.清空排练表
        timetableRechearsalMapper.deleteAll();
        //2.准备排练数据
        Long semesterId = timetable.getSemesterId();
        timetableRechearsalMapper.insertRehearsalData(semesterId);

        int timeslot1 = timetable.getTimeslot();
        List<Integer> list = new ArrayList<>();
        for (int timeslot2 = 0;timeslot2 <= ClassUtil.MAX_WEEK_TIMESLOT;timeslot2++){
            if (timeslot1 == timeslot2){
                continue;
            }
            //更新排练数据
            timetableRechearsalMapper.updateRehearsalData(id,timeslot2);
            //进行排练 返回0条数据表示无冲突，其它情况(其实也就只会返回1条) 表示有冲突
            TimetableRehearsal timetableRehearsal = timetableRechearsalMapper.rehearsalChangeTimeslot(id);

            if (timetableRehearsal == null){
                list.add(timeslot2);
            }
        }
        String msg = "成功获取(timetable.id=" + id + "的字段的)可变动目的时间";
        return Result.success(msg,list);
    }

    //获取全部课表
    @Override
    public Result getList() {
        // 明确选择需要的字段，并保证 GROUP BY 完整
        List<Timetable> timetableList = timetableMapper.selectList(new LambdaQueryWrapper<Timetable>()
                .select(Timetable::getTimeslot, Timetable::getClassNo, Timetable::getCourseNo, Timetable::getTeacherNo, Timetable::getRoomNo,Timetable::getSemesterId)
                .groupBy(Timetable::getTimeslot, Timetable::getClassNo, Timetable::getCourseNo, Timetable::getTeacherNo, Timetable::getRoomNo,Timetable::getSemesterId));

        if (timetableList == null || timetableList.isEmpty()){
            return Result.error(400,"该班级没有课表");
        }
        //过滤出班级、课程、教室编号
        List<String> classNos = timetableList.stream().map(Timetable::getClassNo).distinct().toList();
        List<String> courseNos = timetableList.stream().map(Timetable::getCourseNo).distinct().toList();
        List<String> roomNoS = timetableList.stream().map(Timetable::getRoomNo).distinct().toList();
        List<String> teacherNos = timetableList.stream().map(Timetable::getTeacherNo).distinct().toList();
        List<Long> semesterIdS = timetableList.stream().map(Timetable::getSemesterId).distinct().toList();

        //查询班级、课程、教室信息
        List<Classes> classes = classesService.list(new LambdaQueryWrapper<Classes>().in(Classes::getClassNo,classNos));
        List<Course> courses = courseService.list(new LambdaQueryWrapper<Course>().in(Course::getCourseNo,courseNos));
        List<Room> rooms = roomService.list(new LambdaQueryWrapper<Room>().in(Room::getRoomNo,roomNoS));
        List<Teacher> teachers = teacherService.list(new LambdaQueryWrapper<Teacher>().in(Teacher::getTeacherNo,teacherNos));
        List<Semester> semesters = semesterService.list(new LambdaQueryWrapper<Semester>().in(Semester::getId,semesterIdS));

        LinkedList<TimeTableClassDto> timeTableClassDtos = new LinkedList<>();
        timetableList.forEach(v->{
            // v 转换成 CoursePlanVo 对象
            TimeTableClassDto timeTableClassDto = new TimeTableClassDto();
            BeanUtils.copyProperties(v,timeTableClassDto);

            //根据教师编号找到教师名称
            classes.stream().filter(t -> t.getClassNo().equals(v.getClassNo())).findFirst().ifPresent(t -> timeTableClassDto.setClassName(t.getClassName()));
            classes.stream().filter(c -> c.getClassNo().equals(v.getClassNo())).findFirst().ifPresent(c -> timeTableClassDto.setSize(c.getSize()));
            courses.stream().filter(c -> c.getCourseNo().equals(v.getCourseNo())).findFirst().ifPresent(c -> timeTableClassDto.setCourseName(c.getCourseName()));
            rooms.stream().filter(r -> r.getRoomNo().equals(v.getRoomNo())).findFirst().ifPresent(r -> timeTableClassDto.setRoomName(r.getRoomName()));
            rooms.stream().filter(r -> r.getRoomNo().equals(v.getRoomNo())).findFirst().ifPresent(r -> timeTableClassDto.setAreaName(r.getAreaName()));
            teachers.stream().filter(t -> t.getTeacherNo().equals(v.getTeacherNo())).findFirst().ifPresent(t -> timeTableClassDto.setTeacherName(t.getTeacherName()));
            semesters.stream().filter(t -> t.getId().equals(v.getSemesterId())).findFirst().ifPresent(t -> timeTableClassDto.setSemesterId(t.getId()));
            semesters.stream().filter(t -> t.getId().equals(v.getSemesterId())).findFirst().ifPresent(t -> timeTableClassDto.setSemesterName(t.getSemesterName()));
            timeTableClassDtos.add(timeTableClassDto);
        });
        return Result.success("返回课表成功",timeTableClassDtos);
    }

    //按班级查课表
    @Override
    public Result getTimetableByClassNo(String classNo) {
        List<TimetableDto> timetableList = timetableMapper.getTimetableByClassNo(classNo);
        return Result.success("查询班级课表成功", timetableList);
    }


    //结构化处理课表数据
    @Override
    public Result queryTimetableByClassNo(List<Timetable> timetableList) {
        //过滤出班级、课程、教室编号
        List<String> classNos = timetableList.stream().map(Timetable::getClassNo).distinct().toList();
        List<String> courseNos = timetableList.stream().map(Timetable::getCourseNo).distinct().toList();
        List<String> roomNos = timetableList.stream().map(Timetable::getRoomNo).distinct().toList();
        List<String> teacherNos = timetableList.stream().map(Timetable::getTeacherNo).distinct().toList();

        //查询班级、课程、教室信息
        List<Classes> classes = classesService.list(new LambdaQueryWrapper<Classes>().in(Classes::getClassNo,classNos));
        List<Course> courses = courseService.list(new LambdaQueryWrapper<Course>().in(Course::getCourseNo,courseNos));
        List<Room> rooms = roomService.list(new LambdaQueryWrapper<Room>().in(Room::getRoomNo,roomNos));
        List<Teacher> teachers = teacherService.list(new LambdaQueryWrapper<Teacher>().in(Teacher::getTeacherNo,teacherNos));

        LinkedList<TimeTableClassDto> timeTableClassDtos = new LinkedList<>();
        timetableList.forEach(v->{
            //将v转换为TimeTableClassDto对象
            TimeTableClassDto timeTableClassDto = new TimeTableClassDto();
            BeanUtils.copyProperties(v,timeTableClassDto);

            //根据教师编号找到教师名称
            classes.stream().filter(t->t.getClassNo().equals(v.getClassNo())).findFirst().ifPresent(t->timeTableClassDto.setClassName(t.getClassName()));
            classes.stream().filter(t->t.getClassNo().equals(v.getClassNo())).findFirst().ifPresent(t->timeTableClassDto.setSize(t.getSize()));
            courses.stream().filter(c -> c.getCourseNo().equals(v.getCourseNo())).findFirst().ifPresent(c -> timeTableClassDto.setCourseName(c.getCourseName()));
            rooms.stream().filter(r -> r.getRoomNo().equals(v.getRoomNo())).findFirst().ifPresent(r -> timeTableClassDto.setRoomName(r.getRoomName()));
            rooms.stream().filter(r -> r.getRoomNo().equals(v.getRoomNo())).findFirst().ifPresent(r -> timeTableClassDto.setAreaName(r.getAreaName()));
            teachers.stream().filter(t -> t.getTeacherNo().equals(v.getTeacherNo())).findFirst().ifPresent(t -> timeTableClassDto.setTeacherName(t.getTeacherName()));
            timeTableClassDtos.add(timeTableClassDto);
        });
        return Result.success("查询班级课表成功",timeTableClassDtos);
    }

    //手动调整课程时间

    /**
     *
     * @param srcId 需要调整的课程表id
     * @param destTimeslot 调整到的新时间段
     * @return
     */
    @Override
    public Result adjust(Long srcId, Integer destTimeslot) {
        Timetable timetable = super.getById(srcId);
        if (timetable == null){
            return Result.error(400,"待调整课程不存在");
        }
        timetable.setTimeslot(destTimeslot);
        boolean b = super.updateById(timetable);
        return b ? Result.success("调整课表成功") : Result.error(400,"调整课表失败");
    }
}
